package com.scalar.chiptrack.adaptor.akrossilicon.sales;

import com.scalar.ScalarException;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.XLSParserImpl;
import com.scalar.chiptrack.commons.Address;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.sales.parser.CustomerInfo;
import com.scalar.chiptrack.sales.parser.CustomerParserDAO;
import com.scalar.chiptrack.utils.Logger;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * User: Sujan
 */
public class CustomerParser {
    private Logger m_parserLogger = null;

    public CustomerParser() throws Exception {
        try {
            m_parserLogger = new Logger("./logs", "customerPorting", "Parser", "debug", 1024 * 1000, 5 );
            //m_parserLogger = AdaptorUtils.getDataParserLogger(".", "customerParser");
            AdaptorUtils.setLogger(m_parserLogger);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void execute() throws Exception {
        boolean success = false;
        AdaptorUtils.printHeader("CUSTOMER PORTING", "PARSER");
        File customerFile = getFileForPorting(System.getProperty("customerPortingFile"));
        log("Parsing Customer Porting File:" + customerFile.getName());
        System.out.println("Parsing Customer Porting File:" + customerFile.getName());
        ArrayList customerList = parseCustomerXLSFile(customerFile);//new ArrayList ( customerCollection );
        log("Parsing completed successfully...");
        System.out.println("Parsing completed successfully.....");
        log("Porting Customer info...");
        System.out.println("Porting Customer info...");
        DBTransaction dbTransaction = null;
        try {
            dbTransaction = DBTransaction.getInstance();
            dbTransaction.begin();
            createUpdateCustomers(dbTransaction, customerList.iterator());
            if (dbTransaction != null) {
                dbTransaction.commit();
            }
            success = true;
        }
        catch (Exception e) {
            m_parserLogger.logDebug("Exception while porting customers:" + e.getMessage(), e);
            e.printStackTrace();
            throw e;
        }
        finally {
            if (dbTransaction != null) {
                if (!success) {
                    dbTransaction.rollback();
                }
                dbTransaction = null;
            }
        }
        if (success) //SEND PORTING STATUS MAIL
        {
            log("Porting Customer info completed successfully....");
            System.out.println("Porting Customer info completed successfully....");

        } else {
            log("**ERROR**Unable to port the customer information....");
            System.out.println("**ERROR**Unable to port the customer information...");
        }
        System.out.println("*** PLEASE SEE THE LOG FILE FOR NOT PORTED CUSTOMERS ***");
    }

    private void log(String message) {
        if (message == null) return;

        if (m_parserLogger != null) {
            m_parserLogger.logDebug(message + AdaptorConstants.LINE_SEPARATOR);
        } else {
            System.out.println(message);
        }
    }

    private File getFileForPorting(String customerPortingFile) throws ScalarException {
        if (customerPortingFile == null || customerPortingFile.trim().length() == 0) {
            log("***ERROR***Customer Porting File Name not specified");
            System.out.println("***ERROR***Customer Porting File Name not specified");
            throw new ScalarException("Customer Porting File Name not specified");
        }
        File portingFile = new File(customerPortingFile);
        if (!portingFile.exists() && !portingFile.isFile()) {
            log("Customer Porting File:" + customerPortingFile + " Does not exist");
            throw new ScalarException(customerPortingFile + " does not exist");
        } else {
            log("Customer Porting File:" + customerPortingFile + " Found");
            System.out.println("Customer Porting File:" + customerPortingFile + " Found");
        }
        return portingFile;
    }

    public static void main(String[] agrs) throws Exception {
        CustomerParser customerParser = new CustomerParser();
        customerParser.execute();
    }

    private void createUpdateCustomers(DBTransaction dbTransaction, Iterator customerIterator) throws ScalarException {
        final int defaultBillingAddressStatusCode = 1;
        final int defaultShippingAddressStatusCode = 2;
        CustomerInfo customerInfo = null;
        int customerId = -1;
        while (customerIterator.hasNext()) {
            customerInfo = (CustomerInfo) customerIterator.next();
            //int dbCustId = CustomerParserDAO.getCustomerId(dbTransaction,customerInfo.getCustomerNumber());
            customerId = CustomerParserDAO.saveCustomer(dbTransaction, customerInfo.getCustomerName(), customerInfo.getCustomerNumber(), customerInfo.getDeliveryTerms(), Constants.CUSTOMER_TYPE_CUSTOMER, customerInfo.getContactPerson(), customerInfo.isDistributor(), customerInfo.getRegion(), customerInfo.getShippingMethod(), customerInfo.getShippingAccountNumber());
            int addrsStatusCode = 0;
            if (customerId > 0) {
                if (customerInfo.getBillingAddress() != null) {
                    ArrayList billingAddresses = new ArrayList();
                    billingAddresses.add(customerInfo.getBillingAddress());
                    addrsStatusCode = CustomerParserDAO.saveCustomerAddresses(dbTransaction, customerId, billingAddresses, "BILLING");
                }
                /*if ( (addrsStatusCode & defaultBillingAddressStatusCode) != defaultBillingAddressStatusCode ) //NO DEFAULT BILLING ADDRESS
                {
                    log ( "NO Default Billing Address Found For the Customer:" +  customerInfo.getCustomerName() );
                }*/

                addrsStatusCode = CustomerParserDAO.saveCustomerAddresses(dbTransaction, customerId, customerInfo.getShippingAddresses(), "SHIPPING");

                /*if ( (addrsStatusCode & defaultShippingAddressStatusCode) != defaultShippingAddressStatusCode ) //NO DEFAULT SHIPPING ADDRESS
                {
                    log ( "NO Default Shipping Address Found For the Customer:" +  customerInfo.getCustomerName() );
                }*/
            } else {
                log("****ERROR***Could not create Customer:" + customerInfo.getCustomerName());
                System.out.println("****ERROR***Could not create Customer:" + customerInfo.getCustomerName());
            }
        }
    }

    private ArrayList parseCustomerXLSFile(File customerPortingFile) throws Exception {
        CustomerInfo customerInfo = null;
        ArrayList customerList = new ArrayList();

        ParserResult result = null;
        Parser parser = ParserFactory.getXLSParser(customerPortingFile);

        ((XLSParserImpl) parser).setHeaderRowIdx(0);
        ((XLSParserImpl) parser).setDataStartRowIdx(1);

        log("\nFound " + customerPortingFile.getAbsolutePath());
        log("\nParsing the file for customers...");
        System.out.println("\nFound " + customerPortingFile.getAbsolutePath());
        System.out.println("\nParsing the file for customers...");

        result = parser.parse();
        Map<String, CustomerInfo> custMap = new HashMap<String, CustomerInfo>();
        while (result.next()) {
            try {
                String custCode = result.getString("Cust Code");
                String custName = result.getString("Company Name");
                if (custName != null && custName.length() > 0) {
                    if (custMap.containsKey(custName)) {
                        customerInfo = custMap.get(custName);
                        customerInfo.setCustomerNumber(customerInfo.getCustomerNumber() + "#" + custCode);
                    } else {
                        customerInfo = new CustomerInfo();
                        customerInfo.setCustomerName(custName);
                        customerInfo.setCustomerNumber(custCode);
                        custMap.put(custName, customerInfo);
                        customerList.add(customerInfo);
                    }

                } else {
                    log("IGNORING: Customer Name Missing for the Row:" + (result.getFileRowIdx()+1));
                    continue;
                }
                Address shippingAddress = null;
                shippingAddress = new Address();
                shippingAddress.setAddress1(custName);
                shippingAddress.setAddress2(result.getString("Ship To Address1"));
                shippingAddress.setAddress3(result.getString("Ship To Address2"));
                shippingAddress.setAddress4(result.getString("Ship To Address3"));
                shippingAddress.setCity(result.getString("Ship To City"));
                shippingAddress.setState(result.getString("Ship Toi State"));
                shippingAddress.setZipCode(result.getString("Ship To Zip"));
                shippingAddress.setCountry(result.getString("Ship To Country"));
                shippingAddress.setPhoneNumber(result.getString("Ship-to Telephone"));
                shippingAddress.setContactPerson(result.getString("Ship-to Attention"));
                shippingAddress.setEmail(result.getString("Ship to Email"));
                shippingAddress.setTagName(custCode);

                if (customerInfo.getShippingAddresses() == null || customerInfo.getShippingAddresses().size() == 0) {
                    shippingAddress.setDefaultAddress("true");
                }

                customerInfo.addShippingAddress(shippingAddress);

                customerInfo.setRegion(result.getString("Ship to GEO"));

                customerInfo.setShippingMethod(result.getString("Preferred Shipping Method"));
                customerInfo.setShippingAccountNumber(result.getString("Shipping Account Number"));

                if (custCode.endsWith("001")) {
                    customerInfo.setBillingAddress(shippingAddress);
                }
            } catch ( Exception e ) {
                m_parserLogger.logDebug("**ERROR** Exception while parsing the Row: " + (result.getFileRowIdx()+1));
            }
        }
        return customerList;
    }
}
